package com.ffcs.crmd.tsp.task.core;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.ffcs.crmd.tsp.api.task.ITspTask;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.enu.ServiceState;
import com.ffcs.crmd.tsp.common.exception.TspException;
import com.ffcs.crmd.tsp.task.config.TaskConfig;
import com.ffcs.crmd.tsp.task.log.TaskLogger;
import com.ffcs.crmd.tsp.task.netty.NettyConfig;

/**
 * 
 * 功能说明:客户端
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class TspTask implements ITspTask {
    
    /**
     * 日志
     */
    private static final Logger LOG          = TaskLogger.getLogger(LoggerName.TaskLoggerName);
    
    /**
     * 任务执行端服务实例
     */
    private TspTaskIntance      clientIntance;
    
    /**
     * 任务执行端启动状态
     */
    private ServiceState        serviceState = ServiceState.CREATE_JUST;
    
    /**
     * 服务器地址
     */
    private String              serverAddr;
    
    /**
     * 任务端标识
     */
    private String              identity;
    
    /**
     * Netty接收处理任务请求线程池
     */
    private int                 processorExecutorThreads;
    
    /**
     * 服务端回调线程池大小
     */
    private int                 callbackExecutorThreads;
    
    /**
     * 子任务执行线程
     */
    private int                 jobProcessThread;
    
    /**
     * 子任务批量业务数据处理线程
     */
    private int                 jobProcessBusinessThread;
    
    /**
     * 重试返回完成任务间隔时间
     */
    private long                retryReturnCompleteJobDetailInterval;
    
    /**
     * 定时打印线程池信息间隔时间
     */
    private long                printThreadPoolInfoInterval;
    
    @Override
    public void start() throws TspException {
        if (StringUtils.isBlank(serverAddr)) {
            throw new TspException("serverAddr is null");
        }
        
        if (StringUtils.isBlank(identity)) {
            throw new TspException("identity is null");
        }
        
        synchronized (this) {
            NettyConfig nettyConfig = new NettyConfig(serverAddr);
            nettyConfig.setProcessorExecutorThreads(processorExecutorThreads);
            nettyConfig.setCallbackExecutorThreads(callbackExecutorThreads);
            
            TaskConfig taskConfig = new TaskConfig();
            taskConfig.setIdentity(identity);
            taskConfig.setJobProcessBusinessThread(jobProcessBusinessThread);
            taskConfig.setJobProcessThread(jobProcessThread);
            taskConfig.setPrintThreadPoolInfoInterval(printThreadPoolInfoInterval);
            taskConfig.setRetryReturnCompleteJobDetailInterval(retryReturnCompleteJobDetailInterval);
            clientIntance = new TspTaskIntance(nettyConfig, taskConfig);
            switch (serviceState) {
                case CREATE_JUST:
                    serviceState = ServiceState.START_FAILED;
                    clientIntance.start();
                    serviceState = ServiceState.RUNNING;
                    LOG.info("TSP-TASK: task start ok identity=[{}] server=[{}].", identity, serverAddr);
                    System.out.println(String.format("TSP-TASK: start task ok identity=[%s] server=[%s].", identity, serverAddr));
                    break;
                case RUNNING:
                    throw new TspException("task is running.");
                case SHUTDOWN_ALREADY:
                    throw new TspException("task has been shutdowned.");
                case START_FAILED:
                    throw new TspException("task start fail before, please start once");
            }
        }
    }
    
    @Override
    public void shutdown() throws TspException {
        synchronized (this) {
            switch (serviceState) {
                case CREATE_JUST:
                    throw new TspException("task is't running");
                case RUNNING:
                    clientIntance.shutdown();
                    serviceState = ServiceState.SHUTDOWN_ALREADY;
                    LOG.info("TSP-TASK: task shutdown ok identity=[{}] server=[{}].", identity, serverAddr);
                    System.out.println(String.format("TSP-TASK: task shutdown task ok identity=[%s] server=[%s].", identity, serverAddr));
                    break;
                case SHUTDOWN_ALREADY:
                    throw new TspException("task has shutdowned before, please start once");
                case START_FAILED:
                    throw new TspException("task start fail before, please start once");
            }
        }
    }
    
    /**
     * 功能说明: 获取Netty接收处理任务请求线程池
     *
     * @return processorExecutorThreads 接收任务
     */
    public int getProcessorExecutorThreads() {
        return processorExecutorThreads;
    }
    
    /**
     * 功能说明: 设置Netty接收处理任务请求线程池
     *
     * @param processorExecutorThreads 接收任务 
     */
    public void setProcessorExecutorThreads(int processorExecutorThreads) {
        this.processorExecutorThreads = processorExecutorThreads;
    }
    
    /**
     * 功能说明: 获取子任务执行线程
     *
     * @return jobProcessThread 子任务执行线程
     */
    public int getJobProcessThread() {
        return jobProcessThread;
    }
    
    /**
     * 功能说明: 设置子任务执行线程
     *
     * @param jobProcessThread 子任务执行线程 
     */
    public void setJobProcessThread(int jobProcessThread) {
        this.jobProcessThread = jobProcessThread;
    }
    
    /**
     * 功能说明: 获取子任务批量业务数据处理线程
     *
     * @return jobProcessBusinessThread 子任务批量业务数据处理线程
     */
    public int getJobProcessBusinessThread() {
        return jobProcessBusinessThread;
    }
    
    /**
     * 功能说明: 设置子任务批量业务数据处理线程
     *
     * @param jobProcessBusinessThread 子任务批量业务数据处理线程 
     */
    public void setJobProcessBusinessThread(int jobProcessBusinessThread) {
        this.jobProcessBusinessThread = jobProcessBusinessThread;
    }
    
    /**
     * 功能说明: 获取重试返回完成任务间隔时间
     *
     * @return retryReturnCompleteJobDetailInterval 重试返回完成任务间隔时间
     */
    public long getRetryReturnCompleteJobDetailInterval() {
        return retryReturnCompleteJobDetailInterval;
    }
    
    /**
     * 功能说明: 设置重试返回完成任务间隔时间
     *
     * @param retryReturnCompleteJobDetailInterval 重试返回完成任务间隔时间 
     */
    public void setRetryReturnCompleteJobDetailInterval(long retryReturnCompleteJobDetailInterval) {
        this.retryReturnCompleteJobDetailInterval = retryReturnCompleteJobDetailInterval;
    }
    
    /**
     * 功能说明: 获取定时打印线程池信息间隔时间
     *
     * @return printThreadPoolInfoInterval 定时打印线程池信息间隔时间
     */
    public long getPrintThreadPoolInfoInterval() {
        return printThreadPoolInfoInterval;
    }
    
    /**
     * 功能说明: 设置定时打印线程池信息间隔时间
     *
     * @param printThreadPoolInfoInterval 定时打印线程池信息间隔时间 
     */
    public void setPrintThreadPoolInfoInterval(long printThreadPoolInfoInterval) {
        this.printThreadPoolInfoInterval = printThreadPoolInfoInterval;
    }
    
    /**
     * 功能说明: 获取服务器地址
     *
     * @return serverAddr 服务器地址
     */
    public String getServerAddr() {
        return serverAddr;
    }
    
    /**
     * 功能说明: 设置服务器地址
     *
     * @param serverAddr 服务器地址 
     */
    public void setServerAddr(String serverAddr) {
        this.serverAddr = serverAddr;
    }
    
    /**
     * 功能说明: 获取任务端标识
     *
     * @return identity 任务端标识
     */
    public String getIdentity() {
        return identity;
    }
    
    /**
     * 功能说明: 设置任务端标识
     *
     * @param identity 任务端标识 
     */
    public void setIdentity(String identity) {
        this.identity = identity;
    }
    
    /**
     * 功能说明: 获取服务端回调线程池大小
     *
     * @return callbackExecutorThreads 服务端回调线程池大小
     */
    public int getCallbackExecutorThreads() {
        return callbackExecutorThreads;
    }
    
    /**
     * 功能说明: 设置服务端回调线程池大小
     *
     * @param callbackExecutorThreads 服务端回调线程池大小 
     */
    public void setCallbackExecutorThreads(int callbackExecutorThreads) {
        this.callbackExecutorThreads = callbackExecutorThreads;
    }
    
}
